package com.flyco.modules.sync.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.flyco.common.api.vo.Result;
import com.flyco.common.util.oConvertUtils;
import com.flyco.modules.mdm.entity.Channel;
import com.flyco.modules.mdm.entity.Customer;
import com.flyco.modules.mdm.entity.CustomerAddress;
import com.flyco.modules.mdm.entity.CustomerChannel;
import com.flyco.modules.mdm.service.IChannelService;
import com.flyco.modules.mdm.service.ICustomerAddressService;
import com.flyco.modules.mdm.service.ICustomerChannelService;
import com.flyco.modules.mdm.service.ICustomerService;
import com.flyco.modules.ums.entity.*;
import com.flyco.modules.ums.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Api(tags="基础数据同步")
@RestController
@RequestMapping("/mdm")
public class MdmController {

    @Autowired
    private IChannelService channelService;
    @Autowired
    private IUmsChannelInfoService umsChannelInfoService;
    @Autowired
    private ICustomerService customerService;
    @Autowired
    private ICustomerAddressService customerAddressService;
    @Autowired
    private ICustomerChannelService customerChannelService;
    @Autowired
    private IUmsMemberService umsMemberService;
    @Autowired
    private IUmsDistributorService distributorService;
    @Autowired
    private IUmsMemberReceiveAddressService umsMemberReceiveAddressService;
    @Autowired
    private IUmsMemberChannelService umsMemberChannelService;

    /**
     * 同步渠道
     *
     * @return
     */
    @ApiOperation(value="渠道-同步", notes="渠道-同步")
    @GetMapping(value = "/syncChannel")
    public Result<?> syncChannel() {
        List<Channel> channelList = channelService.list();
        List<UmsChannelInfo> channelInfos = new ArrayList<>();
        channelList.forEach(r->{
            UmsChannelInfo c = new UmsChannelInfo();
            c.setId(c.getId());
            c.setExtCode(r.getChannelCode());
            c.setName(r.getChannelName());
            c.setExtParentCode(r.getParentChannelCode());
            // 后续根据配置动态设置商家
            c.setPartnerId(3L);
            channelInfos.add(c);
        });
        if (channelInfos.size() >0) {
            umsChannelInfoService.saveOrUpdateBatch(channelInfos);
        }
        return Result.ok("同步成功！");
    }

    /**
     * 同步经销商渠道
     *
     * @return
     */
    @ApiOperation(value="经销商渠道-同步", notes="经销商渠道-同步")
    @GetMapping(value = "/syncCustomerChannel")
    public Result<?> syncCustomerChannel() {
        getCustomerChannel(1,500);
        return Result.ok("同步成功！");
    }

    private void getCustomerChannel(Integer pageNo, Integer pageSize) {
        Page<CustomerChannel> page = new Page<>(pageNo,pageSize);
        IPage<CustomerChannel> pageList = customerChannelService.page(page);
        List<UmsMemberChannel> memberChannels = new ArrayList<>();
        if (pageList.getRecords().size() > 0) {
            pageList.getRecords().forEach(c -> {
                UmsMemberChannel memberChannel = new UmsMemberChannel();
                memberChannel.setId(c.getId());
                memberChannel.setChannelCode(c.getChannelCode());
                memberChannel.setCustomerCode(c.getCustomerCode());
                memberChannel.setCompanyCode(c.getCompanyCode());
                // 后续根据配置动态设置商家
                memberChannel.setPartnerId(3L);
                memberChannels.add(memberChannel);
            });
            List<String> customerCodes = memberChannels.stream().map(UmsMemberChannel::getCustomerCode).collect(Collectors.toList());
            LambdaQueryWrapper<UmsDistributor> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.in(UmsDistributor::getCustomerCode,customerCodes);
            List<UmsDistributor> distributors = distributorService.list(queryWrapper);
            List<String> channelCodes = memberChannels.stream().map(UmsMemberChannel::getChannelCode).collect(Collectors.toList());
            LambdaQueryWrapper<UmsChannelInfo> channelQueryWrapper = new LambdaQueryWrapper<>();
            channelQueryWrapper.in(UmsChannelInfo::getExtCode, channelCodes);
            List<UmsChannelInfo> channelList = umsChannelInfoService.list(channelQueryWrapper);
            if (distributors.size() > 0 && channelList.size() > 0) {
                List<UmsMemberChannel> addMemberChannels = new ArrayList<>();
                Map<String, Long> memberMaps = distributors.stream().collect(Collectors.toMap(UmsDistributor::getCustomerCode, UmsDistributor::getMemberId, (key1, key2) -> key2));
                Map<String, Long> channelMaps = channelList.stream().collect(Collectors.toMap(UmsChannelInfo::getExtCode, UmsChannelInfo::getId, (key1, key2) -> key2));

                memberChannels.forEach(m->{
                    if (memberMaps.containsKey(m.getCustomerCode()) && channelMaps.containsKey(m.getChannelCode())) {
                        m.setMemberId(memberMaps.get(m.getCustomerCode()));
                        m.setChannelId(channelMaps.get(m.getChannelCode()));
                        addMemberChannels.add(m);
                    }
                });
                if (addMemberChannels.size() > 0) {
                    umsMemberChannelService.saveOrUpdateBatch(addMemberChannels);
                }
            }
            getCustomerChannel(pageNo+1, pageSize);
        }
    }


    /**
     * 同步经销商
     *
     * @return
     */
    @ApiOperation(value="经销商-同步", notes="经销商-同步")
    @GetMapping(value = "/syncCustomer")
    public Result<?> syncCustomer() {
        getCustomer(1,500);
        return Result.ok("同步成功！");
    }

    private void getCustomer(Integer pageNo, Integer pageSize) {
        Page<Customer> page = new Page<>(pageNo,pageSize);
        IPage<Customer> pageList = customerService.page(page);
        List<UmsDistributor> distributorList = new ArrayList<>();
        List<UmsMember> memberList = new ArrayList<>();
        if (pageList.getRecords().size() > 0) {
            pageList.getRecords().forEach(c -> {
                UmsDistributor distributor = new UmsDistributor();
                BeanUtils.copyProperties(c,distributor);
                distributorList.add(distributor);
                UmsMember member = new UmsMember();
                //member.setType(c.getCustomerType());
                member.setType(5);
                member.setCustomerCode(c.getCustomerCode());
                member.setName(c.getCustomerName());
                member.setAddress(c.getCustomerAddress());
                member.setMobile(c.getCustomerMobile());
                member.setDepartmentId(c.getDepartmentId());
                member.setProvince(c.getProvince());
                member.setCity(c.getCity());
                member.setRegion(c.getArea());
                member.setCancelFlag(c.getIsDeleted());
                member.setRegTime(c.getCreateTime());
                memberList.add(member);
            });
            List<String> customerCodes = distributorList.stream().map(UmsDistributor::getCustomerCode).collect(Collectors.toList());
            LambdaQueryWrapper<UmsMember> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.in(UmsMember::getCustomerCode,customerCodes);
            List<UmsMember> umsMembers = umsMemberService.list(queryWrapper);
            if (umsMembers.size() > 0) {
                Map<String, Long> memberMaps = umsMembers.stream().collect(Collectors.toMap(UmsMember::getCustomerCode, UmsMember::getId, (key1, key2) -> key2));
                memberList.forEach(m->{
                    if (memberMaps.containsKey(m.getCustomerCode())) {
                        m.setId(memberMaps.get(m.getCustomerCode()));
                    }
                });
            }
            if (memberList.size() > 0) {
                umsMemberService.saveOrUpdateBatch(memberList);
                Map<String, Long> memberMaps = memberList.stream().collect(Collectors.toMap(UmsMember::getCustomerCode, UmsMember::getId, (key1, key2) -> key2));
                distributorList.forEach(d->{
                    if (memberMaps.containsKey(d.getCustomerCode())) {
                        d.setMemberId(memberMaps.get(d.getCustomerCode()));
                    }
                });
                distributorService.saveOrUpdateBatch(distributorList);
            }
            getCustomer(pageNo+1, pageSize);
        }
    }

    /**
     * 同步经销商地址
     *
     * @return
     */
    @ApiOperation(value="经销商地址-同步", notes="经销商地址-同步")
    @GetMapping(value = "/syncCustomerAddress")
    public Result<?> syncCustomerAddress() {
        getCustomerAddress(1,500);
        return Result.ok("同步成功！");
    }

    private void getCustomerAddress(Integer pageNo, Integer pageSize) {
        Page<CustomerAddress> page = new Page<>(pageNo,pageSize);
        IPage<CustomerAddress> pageList = customerAddressService.page(page);
        List<UmsMemberReceiveAddress> receiveAddresses = new ArrayList<>();
        if (pageList.getRecords().size() > 0) {
            pageList.getRecords().forEach(c -> {
                UmsMemberReceiveAddress receiveAddress = new UmsMemberReceiveAddress();
                receiveAddress.setCustomerCode(c.getCustomerCode());
                receiveAddress.setDetailAddress(c.getAddress());
                receiveAddress.setPhoneNumber(c.getMobile());
                receiveAddress.setName(c.getConsignee());
                receiveAddress.setProvince(c.getProvince());
                receiveAddress.setCity(c.getCity());
                receiveAddress.setRegion(c.getArea());
                receiveAddress.setDefaultStatus(c.getIsDefault());
                receiveAddress.setDelFlag(  oConvertUtils.isEmpty(c.getIsDeleted()) ? "0" : String.valueOf(c.getIsDeleted()) );
                receiveAddress.setThirdId(c.getId());
                receiveAddresses.add(receiveAddress);
            });
            List<String> customerCodes = receiveAddresses.stream().map(UmsMemberReceiveAddress::getCustomerCode).collect(Collectors.toList());
            LambdaQueryWrapper<UmsDistributor> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.in(UmsDistributor::getCustomerCode,customerCodes);
            List<UmsDistributor> distributors = distributorService.list(queryWrapper);
            if (distributors.size() > 0) {
                List<UmsMemberReceiveAddress> addReceiveAddresses = new ArrayList<>();
                Map<String, Long> memberMaps = distributors.stream().collect(Collectors.toMap(UmsDistributor::getCustomerCode, UmsDistributor::getMemberId, (key1, key2) -> key2));
                receiveAddresses.forEach(r->{
                    if (memberMaps.containsKey(r.getCustomerCode())) {
                        r.setMemberId(memberMaps.get(r.getCustomerCode()));
                        addReceiveAddresses.add(r);
                    }
                });
                if (addReceiveAddresses.size() > 0) {
                    List<Long> thirdIds = addReceiveAddresses.stream().map(UmsMemberReceiveAddress::getThirdId).collect(Collectors.toList());
                    LambdaQueryWrapper<UmsMemberReceiveAddress> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                    lambdaQueryWrapper.in(UmsMemberReceiveAddress::getThirdId, thirdIds);
                    List<UmsMemberReceiveAddress> addressList = umsMemberReceiveAddressService.list(lambdaQueryWrapper);
                    Map<Long, Long> addressIds = addressList.stream().collect(Collectors.toMap(UmsMemberReceiveAddress::getThirdId, UmsMemberReceiveAddress::getId, (key1, key2) -> key2));
                    addReceiveAddresses.forEach(a->{
                        if (addressIds.containsKey(a.getThirdId())) {
                            a.setId(addressIds.get(a.getThirdId()));
                        }
                    });
                    umsMemberReceiveAddressService.saveOrUpdateBatch(addReceiveAddresses);
                }
            }
            getCustomerAddress(pageNo+1, pageSize);
        }
    }


}
